package com.yds.developtools.utils

import android.content.Intent
import android.net.Uri
import android.provider.MediaStore
import org.xutils.common.Callback
import org.xutils.http.RequestParams
import org.xutils.x
import java.io.File
import java.io.FileNotFoundException
import java.util.*

/**
 * 作者:     YDS
 * 创建时间: 2023/5/29 16:12
 * 页面描述: Xutils文件下载帮助类
 */
@Suppress("unused")
object YDSXutilsDownloadFileHelper : YDSBaseHelper() {
    private var cancelable: Callback.Cancelable? = null
    private val mCallbackMap: MutableMap<String, Callback.Cancelable?> =
        HashMap<String, Callback.Cancelable?>()

    /**
     * 下载文件
     *
     * @param fileUrl
     * @param filePath
     * @param callBack
     */
    fun downloadFile(fileUrl: String, filePath: String, callBack: CommonFileCallBack<String>) {
        downloadFile(fileUrl, filePath, false, callBack)
    }

    /**
     * 下载文件
     *
     * @param fileUrl
     * @param filePath
     * @param updateAlbum
     * @param callBack
     */
    @Suppress("unused")
    fun downloadFile(
        fileUrl: String, filePath: String,
        updateAlbum: Boolean, callBack: CommonFileCallBack<String>
    ) {
        if (filePath.isEmpty()) {
            throw RuntimeException("FILE PATH IS EMPTY")
        }
        val requestParams = RequestParams(parseUtf8Url(fileUrl))
        requestParams.saveFilePath = filePath
        cancelable = x.http().get(requestParams, object : Callback.ProgressCallback<File> {
            override fun onWaiting() {
                callBack.onWaiting()
            }

            override fun onStarted() {
                callBack.onStarted()
            }

            override fun onLoading(total: Long, current: Long, isDownloading: Boolean) {
                callBack.onLoading((current * 100 / total).toInt())
            }

            override fun onSuccess(file: File) {
                callBack.onSuccess(file.path)
                if (updateAlbum) {
                    updateAlbum(file.path)
                }
            }

            override fun onError(ex: Throwable, isOnCallback: Boolean) {
                callBack.onError(ex.message.toString())
            }

            override fun onCancelled(cex: Callback.CancelledException?) {
                callBack.onCancelled()
            }

            override fun onFinished() {
                callBack.onFinished()
            }
        })
        mCallbackMap[fileUrl] = cancelable
    }

    /*** 作者: YDS 时间: 2023/5/29 16:23 描述: 将url进行encode，解决部分手机无法下载含有中文url的文件的问题 ***/
    @Suppress("DEPRECATION")
    fun parseUtf8Url(url: String): String {
        val sb = StringBuffer()
        for (element in url) {
            if (element.toInt() in 0..255) {
                sb.append(element)
            } else {
                val b: ByteArray = try {
                    element.toString().toByteArray(charset("utf-8"))
                } catch (ex: Exception) {
                    println(ex)
                    ByteArray(0)
                }
                for (j in b.indices) {
                    var k = b[j].toInt()
                    if (k < 0) k += 256
                    sb.append("%" + Integer.toHexString(k).uppercase(Locale.getDefault()))
                }
            }
        }
        return sb.toString()
    }

    /*** 作者: YDS 时间: 2023/5/29 16:25 描述: 利用文件url转换出文件名 ***/
    @Suppress("unused")
    fun parseFileName(url: String): String {
        var fileName: String? = null
        try {
            fileName = url.substring(url.lastIndexOf("/") + 1)
        } finally {
            fileName = fileName ?: System.currentTimeMillis().toString()
        }
        return fileName
    }

    /*** 作者: YDS 时间: 2023/5/29 16:27 描述: 更新相册 ***/
    @Suppress("DEPRECATION")
    fun updateAlbum(filePath: String) {
        val file = File(filePath)
        val fileName = parseFileName(filePath)
        try {
            MediaStore.Images.Media.insertImage(
                getContext().contentResolver,
                file.absolutePath,
                fileName,
                null
            )
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        }
        getContext().sendBroadcast(
            Intent(
                Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                Uri.parse(file.absolutePath)
            )
        )
    }

    /*** 作者: YDS 时间: 2023/5/29 16:30 描述: 请求回调 ***/
    interface CommonFileCallBack<T> {
        fun onWaiting() {}
        fun onStarted() {}
        fun onSuccess(result: T)
        fun onLoading(progress: Int) {}
        fun onError(errorMsg: T) {}
        fun onCancelled() {}
        fun onFinished() {}
    }

    /*** 作者: YDS 时间: 2023/5/29 16:30 描述: 查询Callback.Cancelable ***/
    fun queryRequestCancelable(): Map<String, Callback.Cancelable?> {
        return mCallbackMap
    }

    /*** 作者: YDS 时间: 2023/5/29 16:30 描述: 取消请求-通过url ***/
    fun requestCancelByUrl(url: String) {
        val cancelable: Callback.Cancelable? = mCallbackMap[url]
        cancelable?.cancel()
    }

    /*** 作者: YDS 时间: 2023/5/29 16:30 描述: 取消请求-全部 ***/
    fun requestCancel() {
        if (mCallbackMap.isEmpty()) return
        val iterator: Iterator<Map.Entry<String, Callback.Cancelable?>> =
            mCallbackMap.entries.iterator()
        while (iterator.hasNext()) {
            val entry: Map.Entry<String, Callback.Cancelable?> = iterator.next()
            val cancelable: Callback.Cancelable? = entry.value
            cancelable?.cancel()
        }
    }
}